package com.workflow.backend.controller;

import org.camunda.bpm.engine.*;
import org.camunda.bpm.engine.repository.*;
import org.camunda.bpm.engine.runtime.*;
import org.camunda.bpm.engine.task.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/workflow")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class WorkflowController {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private ManagementService managementService;

    // 部署流程定义
    @PostMapping("/deploy")
    public ResponseEntity<Map<String, Object>> deployProcess(@RequestBody Map<String, String> request) {
        String bpmnXml = request.get("bpmnXml");
        if (bpmnXml == null || bpmnXml.isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of("error", "BPMN XML不能为空"));
        }

        try {
            Deployment deployment = repositoryService.createDeployment()
                    .addInputStream("process.bpmn", new ByteArrayInputStream(bpmnXml.getBytes()))
                    .deploy();

            Map<String, Object> response = new HashMap<>();
            response.put("deploymentId", deployment.getId());
            response.put("deploymentName", deployment.getName());
            response.put("deployedAt", deployment.getDeploymentTime());

            // 获取部署的流程定义
            List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery()
                    .deploymentId(deployment.getId())
                    .list();

            response.put("processDefinitions", processDefinitions.stream().map(pd -> {
                Map<String, Object> pdMap = new HashMap<>();
                pdMap.put("id", pd.getId());
                pdMap.put("key", pd.getKey());
                pdMap.put("name", pd.getName());
                pdMap.put("version", pd.getVersion());
                return pdMap;
            }).collect(Collectors.toList()));

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            return ResponseEntity.status(500).body(Map.of("error", "部署流程失败: " + e.getMessage()));
        }
    }

    // 获取流程定义列表
    @GetMapping("/process-definitions")
    public ResponseEntity<List<Map<String, Object>>> getProcessDefinitions() {
        try {
            List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery()
                    .latestVersion()
                    .list();

            List<Map<String, Object>> response = processDefinitions.stream().map(pd -> {
                Map<String, Object> pdMap = new HashMap<>();
                pdMap.put("id", pd.getId());
                pdMap.put("key", pd.getKey());
                pdMap.put("name", pd.getName());
                pdMap.put("version", pd.getVersion());
                pdMap.put("deploymentId", pd.getDeploymentId());
                pdMap.put("tenantId", pd.getTenantId());
                return pdMap;
            }).collect(Collectors.toList());

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            return ResponseEntity.status(500).build();
        }
    }

    // 启动流程实例
    @PostMapping("/process-instances")
    public ResponseEntity<Map<String, Object>> startProcess(@RequestBody Map<String, Object> request) {
        String processKey = (String) request.get("processKey");
        if (processKey == null || processKey.isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of("error", "流程定义键不能为空"));
        }

        try {
            Map<String, Object> variables = (Map<String, Object>) request.getOrDefault("variables", new HashMap<>());

            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processKey, variables);

            Map<String, Object> response = new HashMap<>();
            response.put("processInstanceId", processInstance.getId());
            response.put("processDefinitionId", processInstance.getProcessDefinitionId());
            // 从processDefinitionId中解析出processDefinitionKey
            String processDefinitionId = processInstance.getProcessDefinitionId();
            String processDefinitionKey = processDefinitionId.split(":")[0];
            response.put("processDefinitionKey", processDefinitionKey);

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            return ResponseEntity.status(500).body(Map.of("error", "启动流程实例失败: " + e.getMessage()));
        }
    }

    // 获取任务列表
    @GetMapping("/tasks")
    public ResponseEntity<List<Map<String, Object>>> getTasks(@RequestParam(required = false) String assignee) {
        try {
            TaskQuery taskQuery = taskService.createTaskQuery();
            if (assignee != null && !assignee.isEmpty()) {
                taskQuery.taskAssignee(assignee);
            }

            List<Task> tasks = taskQuery.list();

            List<Map<String, Object>> response = tasks.stream().map(task -> {
                Map<String, Object> taskMap = new HashMap<>();
                taskMap.put("id", task.getId());
                taskMap.put("name", task.getName());
                taskMap.put("assignee", task.getAssignee());
                taskMap.put("processInstanceId", task.getProcessInstanceId());
                taskMap.put("processDefinitionId", task.getProcessDefinitionId());
                taskMap.put("createTime", task.getCreateTime());
                taskMap.put("dueDate", task.getDueDate());
                return taskMap;
            }).collect(Collectors.toList());

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            return ResponseEntity.status(500).build();
        }
    }

    // 完成任务
    @PostMapping("/tasks/{taskId}/complete")
    public ResponseEntity<Map<String, Object>> completeTask(@PathVariable String taskId, @RequestBody Map<String, Object> request) {
        try {
            Map<String, Object> variables = (Map<String, Object>) request.getOrDefault("variables", new HashMap<>());
            taskService.complete(taskId, variables);

            return ResponseEntity.ok(Map.of("success", true, "message", "任务完成成功"));
        } catch (Exception e) {
            return ResponseEntity.status(500).body(Map.of("error", "完成任务失败: " + e.getMessage()));
        }
    }

    // 部署表单
    @PostMapping("/forms/deploy")
    public ResponseEntity<Map<String, Object>> deployForm(@RequestBody Map<String, String> request) {
        String formKey = request.get("formKey");
        String schema = request.get("schema");

        if (formKey == null || formKey.isEmpty() || schema == null || schema.isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of("error", "表单键和表单模式不能为空"));
        }

        try {
            // 这里简化处理，实际项目中可能需要将表单存储到数据库中
            // 这里我们只是返回成功信息
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("formKey", formKey);
            response.put("message", "表单部署成功");

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            return ResponseEntity.status(500).body(Map.of("error", "部署表单失败: " + e.getMessage()));
        }
    }

    // 获取表单定义
    @GetMapping("/forms/{formKey}")
    public ResponseEntity<Map<String, Object>> getFormDefinition(@PathVariable String formKey) {
        try {
            // 这里简化处理，实际项目中可能需要从数据库中查询表单
            // 这里我们返回一个示例表单
            Map<String, Object> response = new HashMap<>();
            response.put("formKey", formKey);
            response.put("schema", "{\"type\":\"default\",\"components\":[]}");
            response.put("data", "{}");

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            return ResponseEntity.status(500).body(Map.of("error", "获取表单定义失败: " + e.getMessage()));
        }
    }
}